package com.ybg.block.core.dbapi.service.impl;

import com.ybg.block.core.dbapi.entity.FnsCa;
import com.ybg.block.core.dbapi.dao.FnsChaincodeMapper;
import com.ybg.block.core.dbapi.dao.FnsChannelMapper;
import com.ybg.block.core.dbapi.dao.FnsLeagueMapper;
import com.ybg.block.core.dbapi.dao.FnsOrgMapper;
import com.ybg.block.core.dbapi.dao.FnsPeerMapper;
import com.ybg.block.core.dbapi.dao.FnsCaMapper;
import com.ybg.block.core.dbapi.entity.FnsLeague;
import com.ybg.block.core.dbapi.entity.FnsOrg;
import com.ybg.block.core.dbapi.service.FnsCaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybg.block.core.dbapi.vo.FnsCaVO;
import com.ybg.block.core.dbapi.vo.FnsPeerVO;
import com.ybg.block.core.fabricbak.utils.CacheUtil;
import com.ybg.block.core.fabricbak.utils.DateUtil;
import com.ybg.block.core.fabricbak.utils.FabricHelper;
import com.ybg.block.core.fabricbak.utils.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
//import com.alibaba.dubbo.config.annotation.Service;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yanyu
 * @since 2019-11-21
 */
//@Service(version = "1.0.0", interfaceClass = FnsCaService.class)
@Service
@Slf4j
public class FnsCaServiceImpl extends ServiceImpl<FnsCaMapper, FnsCa> implements FnsCaService {
    @Autowired
    private FnsLeagueMapper leagueMapper;
    @Autowired
    private FnsOrgMapper orgMapper;
    @Autowired
    private FnsPeerMapper peerMapper;
    @Autowired
    private FnsCaMapper caMapper;
    @Autowired
    private FnsChannelMapper channelMapper;
    @Autowired
    private FnsChaincodeMapper chaincodeMapper;

    @Override
    public int add(FnsCaVO ca, MultipartFile skFile, MultipartFile certificateFile) {
        if (null == skFile || null == certificateFile) {
            log.debug("ca cert is null");
            return 0;
        }
        if (null != caMapper.check(ca)) {
            log.debug("had the same ca in this peer");
            return 0;
        }
        ca = resetCa(ca);
        try {
            ca.setSk(new String(IOUtils.toByteArray(skFile.getInputStream()), Charset.forName("UTF-8")));
            ca.setCertificate(new String(IOUtils.toByteArray(certificateFile.getInputStream()), Charset.forName("UTF-8")));
        } catch (IOException e) {
            e.printStackTrace();
        }
        ca.setDate(DateUtil.getCurrent("yyyy-MM-dd"));
        CacheUtil.removeHome();
        return caMapper.add(ca);
    }

    @Override
    public int update(FnsCaVO ca, MultipartFile skFile, MultipartFile certificateFile) {
        FabricHelper.obtain().removeChaincodeManager(channelMapper.list(ca.getPeerId()), chaincodeMapper);
        CacheUtil.removeHome();
        CacheUtil.removeFlagCA(ca.getFlag());
        ca = resetCa(ca);
        if (StringUtils.isEmpty(ca.getCertificate()) || StringUtils.isEmpty(ca.getSk())) {
            return caMapper.updateWithNoFile(ca);
        }
        try {
            ca.setSk(new String(IOUtils.toByteArray(skFile.getInputStream())));
            ca.setCertificate(new String(IOUtils.toByteArray(certificateFile.getInputStream()), "UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return caMapper.update(ca);
    }

    @Override
    public List<FnsCaVO> listAll() {
        return caMapper.listAll();
    }

    @Override
    public List<FnsCa> listById(int id) {
        return caMapper.list(id);
    }

    @Override
    public FnsCa get(int id) {
        return caMapper.get(id);
    }

    @Override
    public FnsCa getByFlag(String flag) {
        return caMapper.getByFlag(flag);
    }

    @Override
    public int countById(int id) {
        return caMapper.count(id);
    }

    @Override
    public int count() {
        return caMapper.countAll();
    }

    @Override
    public int delete(int id) {
        FabricHelper.obtain().removeChaincodeManager(channelMapper.list(caMapper.get(id).getPeerId()), chaincodeMapper);
        return caMapper.delete(id);
    }

    @Override
    public List<FnsPeerVO> getFullPeers() {
        List<FnsPeerVO> peers = peerMapper.listAll();
        for (FnsPeerVO peer : peers) {
            FnsOrg org = orgMapper.get(peer.getOrgId());
            peer.setOrgName(org.getMspId());
            FnsLeague league = leagueMapper.get(org.getLeagueId());
            peer.setLeagueName(league.getName());
        }
        return peers;
    }

    @Override
    public List<FnsPeerVO> getPeersByCA(FnsCa ca) {
        FnsOrg org = orgMapper.get(peerMapper.get(ca.getPeerId()).getOrgId());
        List<FnsPeerVO> peers = peerMapper.list(org.getId());
        FnsLeague league = leagueMapper.get(orgMapper.get(org.getId()).getLeagueId());
        for (FnsPeerVO peer : peers) {
            peer.setLeagueName(league.getName());
            peer.setOrgName(org.getMspId());
        }
        return peers;
    }

    @Override
    public List<FnsCaVO> listFullCA() {
        List<FnsCaVO> cas = caMapper.listAll();
        for (FnsCaVO ca: cas) {
            FnsPeerVO peer = peerMapper.get(ca.getPeerId());
            FnsOrg org = orgMapper.get(peer.getOrgId());
            ca.setPeerName(peer.getName());
            ca.setOrgName(org.getMspId());
            ca.setLeagueName(leagueMapper.get(org.getLeagueId()).getName());
        }
        return cas;
    }

    private FnsCaVO resetCa(FnsCaVO ca) {
        FnsPeerVO peer = peerMapper.get(ca.getPeerId());
        FnsOrg org = orgMapper.get(peer.getOrgId());
        FnsLeague league = leagueMapper.get(org.getLeagueId());
        // ca.setName(String.format("%s-%s", ca.getName(), ca.getPeerId()));
        ca.setLeagueName(league.getName());
        ca.setOrgName(org.getMspId());
        ca.setPeerName(peer.getName());
        ca.setFlag(MD5Util.md516(league.getName() + org.getMspId() + peer.getName() + ca.getName()));
        return ca;
    }
}
